package com.heima.service.impl;

import com.heima.component.RedisComponent;
import com.heima.entity.config.AppConfig;
import com.heima.entity.constants.Constants;
import com.heima.entity.dto.SysSettingsDto;
import com.heima.entity.po.EmailCode;
import com.heima.entity.po.UserInfo;
import com.heima.entity.query.EmailCodeQuery;
import com.heima.entity.query.UserInfoQuery;
import com.heima.exception.BusinessException;
import com.heima.mapper.EmailCodeMapper;
import com.heima.mapper.UserInfoMapper;
import com.heima.service.EmailCodeService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;


import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.heima.utils.StringTools.getRandomNumber;


/**
 * 邮箱验证码 业务接口实现
 */
@Service("emailCodeService")
@Slf4j
public class EmailCodeServiceImpl implements EmailCodeService {

    private static final Logger logger = LoggerFactory.getLogger(EmailCodeServiceImpl.class);
    @Resource
    private EmailCodeMapper<EmailCode, EmailCodeQuery> emailCodeMapper;

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private AppConfig appConfig;

    @Resource
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

    @Resource
    private RedisComponent redisComponent;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendEmailCode(String email, Integer type) {
        if(type == 0) {

            UserInfo userInfo = userInfoMapper.selectByEmail(email);

            if (userInfo != null) {
                throw new BusinessException("邮箱已存在");

            }
            String code = getRandomNumber(Constants.NUM_LENGTH);

            //将之前的值置为无效
            emailCodeMapper.disableEmailCode(email);

            sendEmailCode(email,code);
            EmailCode emailDTO = new EmailCode();
            emailDTO.setEmail(email);
            emailDTO.setCode(code);
            emailDTO.setCreateTime(new Date());
            emailDTO.setStatus(Constants.ZERO);

            emailCodeMapper.insert(emailDTO);
        }

            else {
                UserInfo user = userInfoMapper.selectByEmail(email);
                if (user == null) {
                    throw new BusinessException("邮箱不存在");

                }
                String code = getRandomNumber(Constants.NUM_LENGTH);

                //将之前的值置为无效
                emailCodeMapper.disableEmailCode(email);

                sendEmailCode(email,code);
                EmailCode emailDTO = new EmailCode();
                emailDTO.setEmail(email);
                emailDTO.setCode(code);
                emailDTO.setCreateTime(new Date());
                emailDTO.setStatus(Constants.ZERO);

                emailCodeMapper.insert(emailDTO);
            }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void verifyEmailCode(String email,String emailCode) {
        EmailCode emailCode1 = emailCodeMapper.selectByEmailAndCode(email, emailCode);
        if (emailCode1 == null){
            throw new BusinessException("邮箱验证码错误");
        }
        if (emailCode1.getStatus() ==1 || System.currentTimeMillis()-emailCode1.getCreateTime().getTime()>Constants.LENGTH_15*1000*60){
            throw new BusinessException("邮箱验证码已失效");
        }
        emailCodeMapper.disableEmailCode(email);
    }

    private void sendEmailCode(String toEmail,String code){
        List<Integer> list = new ArrayList<>();
        

        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
            helper.setFrom(appConfig.getSendUserName());
            helper.setTo(toEmail);

            SysSettingsDto sysSettingsDto = redisComponent.getsysSettingsDto();
            helper.setSubject(sysSettingsDto.getRegisterEmailTitle());
            helper.setText(String.format(sysSettingsDto.getRegisterEmailContent(),code));
            helper.setSentDate(new Date());

        } catch (Exception e) {
            log.error("邮件发送失败",e);
            throw new BusinessException("邮件发送失败");
        }
    }
}